from socket import *
from threading import Thread


class MYNET:
    '''
    https://blog.csdn.net/weixin_44992737/article/details/125443207
    文档：
    语法格式: class socket(AddressFamily, SocketType, protocol)
    AddressFamily 参数有 AF_INET AF_UNIX AF表示ADDRESS FAMILY地址族
    AF_INET 是IPv4网络协议的套接字类型 AF_UNIX是Unix本地通信
    SocketType 面向连接 SOCK_STREAM 非连接 SOCK_DGRAM

    服务器端套接字函数:
    s.bind(host, port),用元组形式表示地址
    s.listen() 开始tcp监听, 记录可挂起的最大连接数 至少为1 一般为5
    s.accept() 被动接受TCP客户端连接 阻塞式等待连接到来
    客户端套接字:
    s.connect() 主动初始化TCP服务器连接, (hostname, port)
    s.connect_ex() 返回错误码
    公共用途套接字
    s.recv() 数据以字符串形式返回 bufsize指定要接收的最大数据量 flag提供有关消息的其他信息
    s.send() 将string中的数据发送到连接的套接字 返回发送字节数
    s.sendall() 完整发送TCP数据 发送string所有数据 成功返回None
    s.recvfrom() 接收UDP数据 返回(data,address) 
    s.sendto() 发送UDP数据 address是形式为(ipaddr, port)
    s.close() 
    s.getpeername() 返回套接字远程地址 (ipaddr, port)
    s.getsockname() 返回套接字自己的地址
    s.setsockopt(level,optname,value) 设置给定套接字选项的值
    s.getsockopt(level,optname,buflen) 返回套接字选项的值
    s.settimeout(timeout) 设置套接字操作的超时期 单位秒
    s.gettimeout() 返回当前超时的值
    s.fileno() 返回套接字文件描述符
    s.setblocking(flag) 0为非阻塞 1为阻塞
    s.makefile() 创建一个与该套接字相关联的文件
    '''

    def __init__(self):
        pass

    def __del__(self):
        pass

    def udp_server(self):
        # udp 服务端
        s = socket(AF_INET, SOCK_DGRAM)
        s.bind(("127.0.0.1", 9000))
        print("UDP server waiting data...")
        recv_data = []
        while True:
            recv_data = s.recvfrom(1024)
            print(f"收到远程数据：{recv_data[0].decode('gbk')}, from {recv_data[1]}")
            if recv_data[0].decode('gbk') == 'q':
                s.close()
                break

    def udp_client(self):
        s = socket(AF_INET, SOCK_DGRAM)  # 创建UDP类型的套接字
        server_addr = ("127.0.0.1", 666)
        while True:
            data = input("请输入：")
            s.sendto(data.encode("gbk"), server_addr)
            if data == 'q':
                s.close()
                break

    def recv_data(self):
        while True:
            recv_data = self.udp_s.recvfrom(1024)
            recv_content = recv_data[0].decode('gbk')
            print(f"recv:{recv_content},from{recv_data[1]}")
            if recv_content == 'q':
                break

    def send_data(self):
        addr = ("127.0.0.1", 666)
        while True:
            data = input("请输入：")
            self.udp_s.sendto(data.encode("gbk"), addr)
            if data == 'q':
                break

    def udp_fun(self):
        self.udp_s = socket(AF_INET, SOCK_DGRAM)
        self.udp_s.bind(("127.0.0.1", 9000))
        th_1 = Thread(target=self.recv_data)
        th_2 = Thread(target=self.send_data)
        th_1.start()
        th_2.start()
        th_1.join()
        th_2.join()


if __name__ == "__main__":
    n = MYNET()
    # n.udp_server()
    # n.udp_client()
    # n.udp_fun()
        